package com.shiguiwu.springmybatis.javabase.thread;

import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.LockSupport;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @description:
 * @author: stone
 * @date: Created by 2021/6/21 9:58
 * @version: 1.0.0
 * @pakeage: com.shiguiwu.springmybatis.thread
 */
public class LockSupportTests {

    public static final Object lock = new Object();

    private static final ReentrantLock REENTRANT_LOCK = new ReentrantLock();

    private static final Condition CONDITION = REENTRANT_LOCK.newCondition();

    public static void main(String[] args) throws Exception {
        testLockSupportAfter();
    }

    public static void testWaitAndNotify() throws InterruptedException {
        new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + "============>start");
            synchronized (lock) {
                System.out.println("lock===============>");
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("end lock=================>");
            }
        }, "t1").start();

        TimeUnit.SECONDS.sleep(5);
        synchronized (lock) {
            lock.notify();
            System.out.println("notify======================>");
        }
    }


    public static void testWaitAndNotify1() throws InterruptedException {
        new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + "============>start");

            try {
                TimeUnit.SECONDS.sleep(5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (lock) {
                System.out.println("lock===============>");
                try {

                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("end lock=================>");
            }
        }, "t1").start();

        TimeUnit.SECONDS.sleep(1);
        synchronized (lock) {
            lock.notify();
            System.out.println("notify======================>");
        }
    }

    public static void testCondition() throws InterruptedException {
        new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + "==============> start");
            try {
                REENTRANT_LOCK.lock();
                System.out.println("==================== wait start");
                CONDITION.await();
                System.out.println("==================== wait end");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                REENTRANT_LOCK.unlock();
                System.out.println("解锁==========>" + Thread.currentThread().getName());
            }

        }, "condition").start();

        TimeUnit.SECONDS.sleep(5);
        try {
            REENTRANT_LOCK.lock();
            CONDITION.signal();
        } finally {
            REENTRANT_LOCK.unlock();
            System.out.println("解锁==========>" + Thread.currentThread().getName());
        }
    }

    public static void testLockSupport() throws InterruptedException {
        Thread t1 = new Thread(() -> {
            System.out.println("start=====================>" + Thread.currentThread().getName());

            LockSupport.park();
            System.out.println("end==========================>" + Thread.currentThread().getName());

        }, "t1");
        t1.start();
        TimeUnit.SECONDS.sleep(5);

        LockSupport.unpark(t1);
        System.out.println("unpark=======================> end");
    }


    public static void testLockSupportAfter() throws InterruptedException {
        Thread t1 = new Thread(() -> {

            try {
                TimeUnit.SECONDS.sleep(5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("start=====================>" + Thread.currentThread().getName());

            LockSupport.park();
            System.out.println("end==========================>" + Thread.currentThread().getName());

        }, "t1");
        t1.start();
        TimeUnit.SECONDS.sleep(1);
        //先执行unpark方法
        LockSupport.unpark(t1);
        System.out.println("unpark=======================> end");
    }
}


